home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2003 August / MW 8 2003 CD1.iso / Inside Macworld / Product News / gimp-1.2.4.sit / gimp-1.2.4 / plug-ins / perl / Net / Net.xs < prev   
Encoding:
Text File  |  2002-08-27  |  5.8 KB  |  275 lines

  1. #include "config.h"
  2.  
  3. /* dunno where this comes from */
  4. #undef VOIDUSED
  5.  
  6. #include "EXTERN.h"
  7. #include "perl.h"
  8. #include "XSUB.h"
  9. #define NEED_newCONSTSUB
  10. #include "gppport.h"
  11.  
  12. #if !defined(PERLIO_IS_STDIO) && defined(HASATTRIBUTE)
  13. # undef printf
  14. #endif
  15.  
  16. #if 0 /* optimized away ;) */
  17. #include <glib.h>
  18. #endif
  19.  
  20. #if !defined(PERLIO_IS_STDIO) && defined(HASATTRIBUTE)
  21. # define printf PerlIO_stdoutf
  22. #endif
  23.  
  24. #include "../perl-intl.h"
  25.  
  26. #if HAVE_PDL
  27.  
  28. # include <pdlcore.h>
  29.  
  30. #if 0
  31. /* hack, undocumented, argh! */
  32. static Core* PDL; /* Structure hold core C functions */
  33.  
  34. /* get pointer to PDL structure. */
  35. static void need_pdl (void)
  36. {
  37.   SV *CoreSV;
  38.  
  39.   if (!PDL)
  40.     {
  41.       /* Get pointer to structure of core shared C routines */
  42.       if (!(CoreSV = perl_get_sv("PDL::SHARE",FALSE)))
  43.         Perl_croak(__("gimp-perl-pixel functions require the PDL::Core module"));
  44.  
  45.       PDL = (Core*) SvIV(CoreSV);
  46.     }
  47. }
  48. #endif
  49.  
  50. #endif
  51.  
  52. #define is_dynamic(sv)                \
  53.     (strEQ ((sv), "Gimp::Tile")        \
  54.          || strEQ ((sv), "Gimp::PixelRgn")    \
  55.          || strEQ ((sv), "Gimp::GDrawable"))
  56.  
  57. static HV *object_cache;
  58. static int object_id = 100;
  59.  
  60. #define init_object_cache    if (!object_cache) object_cache = newHV()
  61.  
  62. static void destroy_object (SV *sv)
  63. {
  64.   if (object_cache && sv_isobject (sv))
  65.     {
  66.       if (is_dynamic (HvNAME(SvSTASH(SvRV(sv)))))
  67.         {
  68.           int id = SvIV(SvRV(sv));
  69.           hv_delete (object_cache, (char *)&id, sizeof(id), G_DISCARD);
  70.         }
  71.       else
  72.         croak ("Internal error: Gimp::Net #101, please report!");
  73.     }
  74.   else
  75.     croak ("Internal error: Gimp::Net #100, please report!");
  76. }
  77.  
  78. /* allocate this much as initial length */
  79. #define INITIAL_PV    256
  80. /* and increment in these steps */
  81. #define PV_INC        512
  82.  
  83. /* types
  84.  *
  85.  * u            undef
  86.  * a num sv*        array
  87.  * p len cont        pv
  88.  * i int        iv
  89.  * b stash sv        blessed reference
  90.  * r            simple reference
  91.  * h len (key sv)*    hash (not yet supported!)
  92.  * p            piddle (not yet supported!)
  93.  *
  94.  */
  95.  
  96. static void sv2net (int deobjectify, SV *s, SV *sv)
  97. {
  98.   if (SvLEN(s)-SvCUR(s) < 96)
  99.     SvGROW (s, SvLEN(s) + PV_INC);
  100.  
  101.   if (SvROK(sv))
  102.     {
  103.       SV *rv = SvRV(sv);
  104.       if (SvOBJECT (rv))
  105.         {
  106.           char *name = HvNAME (SvSTASH (rv));
  107.  
  108.           sv_catpvf (s, "b%x:%s", strlen (name), name);
  109.  
  110.           if (deobjectify && is_dynamic (name))
  111.             {
  112.               object_id++;
  113.  
  114.               SvREFCNT_inc(sv);
  115.               hv_store (object_cache, (char *)&object_id, sizeof(object_id), sv, 0);
  116.               
  117.               sv_catpvf (s, "i%d:", object_id);
  118.               return; /* well... */
  119.             }
  120.         } 
  121.       else
  122.         sv_catpvn (s, "r", 1);
  123.  
  124.       if (SvTYPE(rv) == SVt_PVAV)
  125.         {
  126.           AV *av = (AV*)rv;
  127.           int i;
  128.  
  129.           sv_catpvf (s, "a%x:", (I32)av_len(av));
  130.           for (i = 0; i <= av_len(av); i++)
  131.             sv2net (deobjectify, s, *av_fetch(av,i,0));
  132.         }
  133.       else if (SvTYPE(rv) == SVt_PVMG)
  134.         sv2net (deobjectify, s, rv);
  135.       else
  136.         croak ("Internal error: unable to convert reference in sv2net, please report!");
  137.     }
  138.   else if (SvOK(sv))
  139.     {
  140.       if (SvIOK(sv))
  141.         sv_catpvf (s,"i%ld:", (long)SvIV(sv));
  142.       else
  143.         {
  144.           char *str;
  145.           STRLEN len;
  146.  
  147.           /* slower than necessary, just make it an pv */
  148.           str = SvPV(sv,len);
  149.           sv_catpvf (s, "p%x:", (int)len);
  150.           sv_catpvn (s, str, len);
  151.         }
  152.     }
  153.   else
  154.     sv_catpvn (s, "u", 1);
  155. }
  156.  
  157. static SV *net2sv (int objectify, char **_s)
  158. {
  159.   char *s = *_s;
  160.   SV *sv;
  161.   AV *av;
  162.   unsigned int ui, n;
  163.   int i, j;
  164.   long l;
  165.   char str[64];
  166.  
  167.   switch (*s++)
  168.     {
  169.       case 'u':
  170.         sv = newSVsv (&PL_sv_undef);
  171.         break;
  172.  
  173.       case 'i':
  174.         sscanf (s, "%ld:%n", &l, &n); s += n;
  175.         sv = newSViv ((IV)l);
  176.         break;
  177.  
  178.       case 'p':
  179.         sscanf (s, "%x:%n", &ui, &n); s += n;
  180.         sv = newSVpvn (s, (STRLEN)ui);
  181.         s += ui;
  182.         break;
  183.  
  184.       case 'r':
  185.         sv = newRV_noinc (net2sv (objectify, &s));
  186.         break;
  187.         
  188.       case 'b':
  189.         sscanf (s, "%x:%n", &ui, &n); s += n;
  190.         if (ui >= sizeof str)
  191.           croak ("Internal error: stashname too long, please report!");
  192.  
  193.         memcpy (str, s, ui); s += ui;
  194.         str[ui] = 0;
  195.  
  196.         if (objectify && is_dynamic (str))
  197.           {
  198.             SV **cv;
  199.             int id;
  200.  
  201.             sscanf (s, "i%ld:%n", &l, &n); s += n;
  202.  
  203.             cv = hv_fetch (object_cache, (char *)(id=l,&id), sizeof(id), 0);
  204.             if (!cv)
  205.               croak ("Internal error: asked to deobjectify an object not in the cache, please report!");
  206.  
  207.             sv = *cv;
  208.             SvREFCNT_inc (sv);
  209.           }
  210.         else
  211.           sv = sv_bless (newRV_noinc (net2sv (objectify, &s)), gv_stashpv (str, 1));
  212.  
  213.         break;
  214.  
  215.       case 'a':
  216.         sscanf (s, "%x:%n", &i, &n); s += n;
  217.         av = newAV ();
  218.         av_extend (av, (I32)i);
  219.         for (j = 0; j <= i; j++)
  220.           av_store (av, (I32)j, net2sv (objectify, &s));
  221.  
  222.         sv = (SV*)av;
  223.         break;
  224.  
  225.       default:
  226.         croak ("Internal error: unable to handle argtype '%c' in net2sv, please report!", s[-1]);
  227.     }
  228.  
  229.   *_s = s;
  230.   return sv;
  231. }
  232.  
  233. MODULE = Gimp::Net    PACKAGE = Gimp::Net
  234.  
  235. PROTOTYPES: ENABLE
  236.  
  237. SV *
  238. args2net(deobjectify,...)
  239.     int    deobjectify
  240.     CODE:
  241.         int index;
  242.  
  243.         if (deobjectify) init_object_cache;
  244.  
  245.         RETVAL = newSVpv ("", 0);
  246.         (void) SvUPGRADE (RETVAL, SVt_PV);
  247.         SvGROW (RETVAL, INITIAL_PV);
  248.  
  249.     for (index = 1; index < items; index++)
  250.           sv2net (deobjectify, RETVAL, ST(index));
  251.  
  252.         OUTPUT:
  253.         RETVAL
  254.  
  255. void
  256. net2args(objectify,s)
  257.       int    objectify
  258.     char *    s
  259.         PPCODE:
  260.  
  261.         if (objectify) init_object_cache;
  262.  
  263.         /* this depends on a trailing zero! */
  264.         while (*s)
  265.       XPUSHs (sv_2mortal (net2sv (objectify, &s)));
  266.  
  267. void
  268. destroy_objects(...)
  269.     CODE:
  270.         int index;
  271.  
  272.         for (index = 0; index < items; index++)
  273.           destroy_object (ST(index));
  274.  
  275.